package com.sinosoft.hydra.um.domain.model;

import cn.com.sinux.spring.utils.FileUtils;
import cn.com.sinux.spring.utils.ValidatorUtils;
import com.sinosoft.hydra.logging.LogModules;
import com.sinosoft.hydra.um.constant.BaseConstant;
import com.sinosoft.hydra.um.domain.permission.TEBom;
import com.sinosoft.hydra.um.domain.permission.TPBom;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Administrator on 2016/7/14.
 */
public class EBOMWordInfo {

    private Map<String, Element> docs;
    private Map<String, Element> imgs;

    private TEBom current;
    private List<TEBom> treeData;
    private List<TEBom> tops;

    private List<TPBom> pBomTreeData;
    private List<TPBom> topPboms;

    private List<LabData> labDatas;

    public Map<String, Element> getImgs() {
        return imgs;
    }

    public Map<String, Element> getDocs() {
        return docs;
    }

    public void buildMap(String relative) {
        int i = 100;
        Set<String> _imgs = new HashSet<String>();
        Set<String> _docs = new HashSet<String>();
        if (StringUtils.isNotBlank(current.getCover())) {
            _imgs.add(current.getCover());
        }
        for (TEBom teBom : treeData) {
            if (StringUtils.isNotBlank(teBom.getCover())) {
                _imgs.add(teBom.getCover());
            }
        }
        for (LabData labData : labDatas) {
            if (labData.getGrantData() != null) {
                if (StringUtils.isNotBlank(labData.getGrantData().getExcelPath())) {
                    _docs.add(labData.getGrantData().getExcelPath());
                }
                if (ValidatorUtils.isArrayNotEmpty(labData.getGrantData().getGrantParams())) {
                    for (GrantParam param : labData.getGrantData().getGrantParams()) {
                        if (BaseConstant.LabelType.LABEL_TYPE_IMG.name().equals(param.getType())
                                && StringUtils.isNotBlank(param.getValue())) {
                            _imgs.add(param.getValue());
                        }
                    }
                }
            }
        }
        this.imgs = new HashMap<String, Element>();
        for (String path : _imgs) {
            String result = doConvert(relative + path);
            if (StringUtils.isNotBlank(result)) {
                this.imgs.put(path, new Element(i, result));
                i++;
            }
        }
    }

    public static class Element {
        private int seq;
        private String data;

        public Element(int seq, String data) {
            this.seq = seq;
            this.data = data;
        }

        public int getSeq() {
            return seq;
        }

        public void setSeq(int seq) {
            this.seq = seq;
        }

        public String getData() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }
    }

    private String doConvert(String filePath) {
        InputStream in = null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] data = null;
        try {
            in = new FileInputStream(filePath);
            FileCopyUtils.copy(in, os);
            data = os.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null)
                    in.close();
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Base64 encoder = new Base64();
        return data != null ? encoder.encodeToString(data) : "";
    }

    public TEBom getCurrent() {
        return current;
    }

    public void setCurrent(TEBom current) {
        this.current = current;
    }

    public List<TEBom> getTreeData() {
        return treeData;
    }

    public void setTreeData(List<TEBom> treeData) {
        this.treeData = treeData;
    }

    public List<TEBom> getTops() {
        return tops;
    }

    public void setTops(List<TEBom> tops) {
        this.tops = tops;
    }

    public List<TPBom> getpBomTreeData() {
        return pBomTreeData;
    }

    public void setpBomTreeData(List<TPBom> pBomTreeData) {
        this.pBomTreeData = pBomTreeData;
    }

    public List<TPBom> getTopPboms() {
        return topPboms;
    }

    public void setTopPboms(List<TPBom> topPboms) {
        this.topPboms = topPboms;
    }

    public List<LabData> getLabDatas() {
        return labDatas;
    }

    public void setLabDatas(List<LabData> labDatas) {
        this.labDatas = labDatas;
    }

    public static class GrantData {
        private String title;
        private String excelPath;
        private List<GrantParam> grantParams;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getExcelPath() {
            return excelPath;
        }

        public void setExcelPath(String excelPath) {
            this.excelPath = excelPath;
        }

        public List<GrantParam> getGrantParams() {
            return grantParams;
        }

        public void setGrantParams(List<GrantParam> grantParams) {
            this.grantParams = grantParams;
        }
    }

    public static class GrantParam {
        private String title;
        private String value;
        private String type;

        public GrantParam(String title, String value, String type) {
            this.title = title;
            this.value = value;
            this.type = type;
        }

        public String getTitle() {
            return title;
        }

        public String getValue() {
            return value;
        }

        public String getType() {
            return type;
        }
    }

    public static class TableInfo{
        private int rowNum = 0;
        private int celNum = 0;
        private List<String> values = new ArrayList<String>();

        public TableInfo(String str) {
            Pattern pattern = Pattern.compile("<tr>");
            Pattern pattern2 = Pattern.compile("<td\\S?[^>]*>([^<]*)<\\/td>");
            Matcher matcher = pattern.matcher(str);
            while (matcher.find()) {
                rowNum++;
            }
            Matcher matcher2 = pattern2.matcher(str);
            while (matcher2.find()) {
                String group = matcher2.group(1);
                values.add(group);
            }
            this.celNum = (values.size() / rowNum);
        }

        public List<String> rowData(int rowNum){
            return this.values.subList(rowNum * celNum, (rowNum+1) * celNum);
        }

        public int getRowNum() {
            return rowNum;
        }

        public int getCelNum() {
            return celNum;
        }

        public List<String> getValues() {
            return values;
        }
    }

    public static class Param {
        private String fieldName;
        private String fieldValue;
        private String device;
        private String unit;

        public Param(String fieldName, String fieldValue, String device, String unit) {
            this.fieldName = fieldName;
            this.fieldValue = fieldValue;
            this.device = device;
            this.unit = unit;
        }

        public void convert(String fieldType, String relativePath, String destPath){
            BaseConstant.FiledType filedType = BaseConstant.FiledType.valueOf(fieldType);
            StringBuilder stringBuilder = new StringBuilder();
            if(Arrays.asList(BaseConstant.FiledType.FIELD_TYPE_SCIENTIFIC, BaseConstant.FiledType.FIELD_TYPE_TABLE).contains(filedType)){
                if(BaseConstant.FiledType.FIELD_TYPE_SCIENTIFIC.equals(filedType)){
                    String[] vv = this.fieldValue.split(",");
                    String v = vv[0], v2 = vv.length < 2 ? "0" : vv[1];
                    stringBuilder.append("<w:p w:rsidR=\"003A4676\" w:rsidRPr=\"00A26378\" w:rsidRDefault=\"003A4676\" w:rsidP=\"003A4676\">");
                    stringBuilder.append("<w:bookmarkStart w:id=\"0\" w:name=\"_GoBack\"/>");
                    stringBuilder.append("<w:bookmarkEnd w:id=\"0\"/>");
                    stringBuilder.append("<w:r><w:rPr><w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>");
                    stringBuilder.append(v).append("×10").append("</w:t></w:r><w:r w:rsidRPr=\"008A4735\"><w:rPr>");
                    stringBuilder.append("<w:rFonts w:hint=\"eastAsia\"/><w:vertAlign w:val=\"superscript\"/></w:rPr><w:t>");
                    stringBuilder.append(v2).append("</w:t></w:r></w:p>");
                }else{
                    TableInfo tableInfo = new TableInfo(this.fieldValue);
                    stringBuilder.append("<w:tbl><w:tblPr><w:tblW w:w=\"0\" w:type=\"auto\"/><w:tblBorders>");
                    stringBuilder.append("<w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append("<w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append("<w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append("<w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append("<w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append("<w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>");
                    stringBuilder.append(" </w:tblBorders>");
                    stringBuilder.append("<w:tblLook w:val=\"04A0\" w:firstRow=\"1\" w:lastRow=\"0\" w:firstColumn=\"1\" w:lastColumn=\"0\" w:noHBand=\"0\" w:noVBand=\"1\"/>");
                    stringBuilder.append("</w:tblPr>");
                    stringBuilder.append("<w:tblGrid>");
                    for(int i =0; i < tableInfo.getCelNum(); i++){
                        stringBuilder.append("<w:gridCol w:w=\"323\"/>");
                    }
                    stringBuilder.append("</w:tblGrid>");
                    for(int i = 0; i < tableInfo.getRowNum(); i++){
                        stringBuilder.append("<w:tr w:rsidR=\"003A4676\" w:rsidRPr=\"00A26378\" w:rsidTr=\"00E93286\">");
                        List<String> celNums = tableInfo.rowData(i);
                        for(String cell : celNums){
                            stringBuilder.append("<w:tc><w:tcPr><w:tcW w:w=\"360\" w:type=\"dxa\"/></w:tcPr>");
                            stringBuilder.append("<w:p w:rsidR=\"003A4676\" w:rsidRDefault=\"003A4676\"><w:r><w:rPr>");
                            stringBuilder.append("<w:rFonts w:hint=\"eastAsia\"/></w:rPr><w:t>").append(cell);
                            stringBuilder.append("</w:t></w:r></w:p></w:tc>");
                        }
                        stringBuilder.append("</w:tr>");
                    }
                    stringBuilder.append("</w:tbl><w:p w:rsidR=\"003A4676\" w:rsidRDefault=\"003A4676\"/>");
                }
            }else{
                stringBuilder.append("<w:p w:rsidR=\"003A4676\" w:rsidRPr=\"00A26378\" w:rsidRDefault=\"003A4676\" w:rsidP=\"003A4676\">");
                stringBuilder.append("<w:pPr><w:rPr><w:sz w:val=\"24\"/><w:szCs w:val=\"24\"/></w:rPr>");
                stringBuilder.append("</w:pPr><w:r w:rsidRPr=\"00A26378\"><w:rPr><w:rFonts w:hint=\"eastAsia\"/><w:sz w:val=\"24\"/>");
                stringBuilder.append("<w:szCs w:val=\"24\"/></w:rPr><w:t>");
                if(BaseConstant.FiledType.FIELD_TYPE_ATTACHMENT.equals(filedType)) {
                    File file = new File(relativePath + fieldValue);
                    if(file.exists()){
                        try {
                            FileUtils.copyFile(file, new File(destPath + "/" + file.getName()));
                        } catch (IOException e) {
                            LoggerFactory.getLogger(LogModules.TRACE_LOGGER).warn("生成报告时实验属性的附件生成失败，失败原因{}", e.getMessage());
                        }
                    }
                    this.fieldValue = file.getName();
                }
                stringBuilder.append(fieldValue);
                stringBuilder.append("</w:t></w:r></w:p>");
            }
            this.fieldValue = stringBuilder.toString();
        }

        public String getFieldName() {
            return fieldName;
        }

        public String getFieldValue() {
            return fieldValue;
        }

        public String getDevice() {
            return device;
        }

        public String getUnit() {
            return unit;
        }
    }

    public static class LabData {
        private String title;
        private String operator;
        private String operateTime;
        private String result;
        private List<Param> params;
        private GrantData grantData;

        public GrantData getGrantData() {
            return grantData;
        }

        public void setGrantData(GrantData grantData) {
            this.grantData = grantData;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public List<Param> getParams() {
            return params;
        }

        public void setParams(List<Param> params) {
            this.params = params;
        }

        public String getOperator() {
            return operator;
        }

        public void setOperator(String operator) {
            this.operator = operator;
        }

        public String getOperateTime() {
            return operateTime;
        }

        public void setOperateTime(String operateTime) {
            this.operateTime = operateTime;
        }

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }
    }
}
